package com.googlecode.smartgwtmavenplugin.mojo;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

import com.googlecode.smartgwtmavenplugin.Archive;
import com.googlecode.smartgwtmavenplugin.PluginContextKeyConstants;

/**
 * Merges default build property values from properties file with standard Maven CLI and settings property values, and adds a few 
 * of it's own, before stroring a collection of Archives to be downloaded from https://www.isomorphic.com/builds into the plugin
 * context.
 * 
 * @goal configure
 * @requiresProject false
 * @requiresDirectInvocation true
 */
public class ConfigureMojo extends AbstractMojo {

	/** @parameter default-value="${session}" */
	private MavenSession session;
	
	/** 
	 * @parameter property="license" 
	 * @required 
	 * */
	Archive license;
	
	/** @parameter property="analytics" default-value=false */
	Boolean analyticsEnabled;
	
	/** @parameter property="messaging" default-value=false */
	Boolean messagingEnabled;
	
	/**
	 * 
	 */
	public void execute() throws MojoExecutionException, MojoFailureException {

		Properties props = new Properties();
		
		//provide runtime property defaults
		String build = Archive.BUILD;
		props.put("build", build);
		
		Boolean snapshot = build.toLowerCase().endsWith("d");
		props.put("snapshot", snapshot);
		
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		String today = dateFormat.format(new Date());
		props.put("build.date", today);

		try {
			props.load(getClass().getResourceAsStream("/configure.properties"));
		} catch (Exception e) {
			throw new MojoFailureException("Default properties not found on classpath.  Allowing execution to proceed, but...");
		}
		
		//merge up with whatever was provided at cli or in a profile, allowing override
		props.putAll(session.getExecutionProperties());

		//validate
		String buildDate = props.getProperty("build.date");
		try {
			dateFormat.parse(buildDate);
		} catch (ParseException e) {
			throw new MojoExecutionException("build.date '" + buildDate + "' must take the form yyyy-MM-dd.");
		}

		//provide any so-called read only property values
		String version = build.replaceFirst("(p|d)", "-$1").concat(buildDate.replace("-", ""));
		if (Boolean.valueOf(props.getProperty("snapshot"))) {
			version += "-SNAPSHOT";
		}
		props.put("version", version);
		
		//and put it back
		session.getExecutionProperties().putAll(props);

		/*
		 * Optional modules are only available to enterprise and power customers, and each optional module requires a
		 * separate download , unpack, install cycle.  Each module may include more than a single archive, as is the case
		 * at version 2.5 of the analytics module (note that later releases contain a single jar).
		 * 
		 * Put everything we're going to need into a set that we can just iterate over when the time comes.
		 */
		Set<Archive> archives = new HashSet<Archive>();
		archives.add(license);
		
		if (license == Archive.POWER || license == Archive.ENTERPRISE) {
			if (analyticsEnabled) {
				archives.add(Archive.ANALYTICS);
			}
			if (messagingEnabled) {
				archives.add(Archive.MESSAGING);
			}
		}
		
		//couldn't make this work through project properties etc., so resort to this plugin context to make complex obects available
		getPluginContext().put(PluginContextKeyConstants.ARCHIVE_SET, archives);
	}

}